package org.example.simple.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * @description: ai 人工智能
 * @author: Jone
 * @create: 2024-06-10
 */
@RestController
@RequestMapping("ai")
public class AiController {

    @Autowired
    private final ChatClient chatClient;
    @Autowired
    private final ChatModel chatModel;
    @Autowired
    private final OpenAiImageOptions openAiImageOptions;
    @Autowired
    private final OpenAiAudioSpeechModel openAiAudioSpeechModel;
    @Autowired
    private final OpenAiTranscriptionModel openAiTranscriptionModel;

    //通过有参构造方法调用
    public AiController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    /**
     * client 模型
     *
     * @param message
     * @return
     */
    @GetMapping("/chat")
    public String generation(@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {
        //prompt： 提示词
        return this.chatClient.prompt()
                .user(message)
                .call()
                .content();
    }

    /**
     * 采用数据流的方式
     */
    //设置相应头
    @GetMapping(value = "/stream", produces = "text/html;charset=UTF-8")
    public Flux<String> stream(@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {
        //prompt： 提示词
        return chatClient.prompt()
                .user("Tell me a joke")
                .stream() //流的形式
                .content();
    }

    /**
     * model 模型
     */
    @GetMapping(value = "/chat/model")
    public String chatModel(@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {
        ChatResponse response = chatModel.call(
                new Prompt(
                        message,
                        OpenAiChatOptions.builder()
                                .withModel("gpt-4-32k")
                                .withTemperature(0.4)
                                .build()
                ));
        return response.getResult().getOutput().getCotent();
    }

    /**
     * 生成图片
     */
    @GetMapping(value = "/test/img")
    public String testImg(@RequestParam(value = "message", defaultValue = "画一个图") String message) {

        ImageResponse response = openaiImageModel.call(
                new ImagePrompt(message,
                        OpenAiImageOptions.builder()
                                .withQuality("hd")
                                .withModel(OpenAiImageApi.DEFAULT_IMAGE_MODEL)
                                .withN(4)
                                .withHeight(1024)
                                .withWidth(1024).build())
        );
        return response.getResult().getOutput().getUrl();
    }

    /**
     * 生成语音
     */
    @GetMapping(value = "/test/audio")
    public String testAudio(@RequestParam(value = "message", defaultValue = "画一个图") String message) throws IOException {

        OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
                .withModel(OpenAiAudioApi.TtsModel.TTS_1.value) //tts-1
                .withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
                .withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
                .withSpeed(1.0f)
                .build();

        SpeechPrompt speechPrompt = new SpeechPrompt("Hello, 这是人工智能语音", speechOptions);
        SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);

        //拿到语音的二进制流
        byte[] body = response.getResult().getOutput();

        writeByteArrayToMp3(body, System.getProperty("user.dir"));

        return "OK";
    }

    /**
     * 保存语音文件
     */
    public static void writeByteArrayToMp3(byte[] audioBytes, String outputFilePath) throws IOException {
        FileOutputStream fos = new FileOutputStream(outputFilePath + "/work");
        fos.write(audioBytes);
        fos.close();
    }

    /**
     * 生成语音 ,语音转文字
     */
    @GetMapping(value = "/test/audioToText")
    public String testAudioToText() {
        //语音翻译的可选配置
        var transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
                .withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.TEXT)
                .withTemperature(0f)
                .build();

        var audioFile = new FileSystemResource("/path/to/your/resource/speech/jfk.flac");

        AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
        AudioTranscriptionResponse response = openAiTranscriptionModel.call(transcriptionRequest);

        return response.getResult().getOutput();
    }

    /**
     * 多模态：包括图片，语音，文本
     */
    @GetMapping(value = "/mutilModel")
    public String mutilModel(@RequestParam(value = "message", defaultValue = "画一个图") String message) throws IOException {

        byte[] imageData = new ClassPathResource("/test.png").getContentAsByteArray();
        var userMessage = new UserMessage(message,List.of(new Media(MimeTypeUtils.IMAGE_PNG,imageData)));

        //ChatModel.GPT_4_TURBO_PREVIEW 改成 4o
        OpenAiChatOptions options = OpenAiChatOptions.builder().withModel(OpenAi.ChatModel.GPT_4_O.getValue()).build();
        ChatResponse response = chatModel.call(new Prompt(userMessage, options);
        return  response.getResult().getOutput().getContent();
    }


}
